package demo.huodongbaoming.controller;

import demo.huodongbaoming.client.CampusActivityClient;
import demo.huodongbaoming.dto.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Zipkin分布式链路跟踪演示控制器
 * 用于展示Zipkin的链路跟踪功能
 */
@RestController
@RequestMapping("/api/zipkin-demo")
public class ZipkinDemoController {

    private static final Logger logger = LoggerFactory.getLogger(ZipkinDemoController.class);

    @Autowired
    private CampusActivityClient campusActivityClient;

    /**
     * 简单的链路跟踪演示
     * @return 响应结果
     */
    @GetMapping("/simple")
    public ResponseResult<Map<String, Object>> simpleTrace() {
        logger.info("进入简单链路跟踪方法");
        
        // 模拟处理时间
        sleep(100);
        
        Map<String, Object> result = new HashMap<>();
        result.put("traceId", "请在Zipkin UI中查看");
        result.put("timestamp", System.currentTimeMillis());
        result.put("message", "简单链路跟踪示例");
        
        logger.info("简单链路跟踪方法执行完成");
        return ResponseResult.success("链路跟踪演示", result);
    }
    
    /**
     * 复杂的链路跟踪演示，包含多个步骤
     * @return 响应结果
     */
    @GetMapping("/complex")
    public ResponseResult<Map<String, Object>> complexTrace() {
        logger.info("进入复杂链路跟踪方法");
        
        // 步骤1：初始化数据
        logger.info("步骤1：初始化数据");
        sleep(50);
        
        // 步骤2：处理业务逻辑
        logger.info("步骤2：处理业务逻辑");
        processBusinessLogic();
        
        // 步骤3：调用外部服务
        logger.info("步骤3：调用外部服务");
        Map<String, Object> serviceResult = callExternalService();
        
        // 步骤4：组装结果
        logger.info("步骤4：组装结果");
        sleep(30);
        
        Map<String, Object> result = new HashMap<>();
        result.put("traceId", "请在Zipkin UI中查看");
        result.put("timestamp", System.currentTimeMillis());
        result.put("message", "复杂链路跟踪示例");
        result.put("serviceResult", serviceResult);
        
        logger.info("复杂链路跟踪方法执行完成");
        return ResponseResult.success("链路跟踪演示", result);
    }
    
    /**
     * 调用微服务链路跟踪演示
     * @param id 活动ID
     * @return 响应结果
     */
    @GetMapping("/activity/{id}")
    public ResponseResult<Map<String, Object>> activityTrace(@PathVariable Long id) {
        logger.info("进入活动链路跟踪方法，活动ID: {}", id);
        
        // 调用活动服务
        Map<String, Object> activity = campusActivityClient.getActivityById(id);
        
        // 处理结果
        sleep(20);
        
        Map<String, Object> result = new HashMap<>();
        result.put("traceId", "请在Zipkin UI中查看");
        result.put("timestamp", System.currentTimeMillis());
        result.put("activity", activity);
        
        logger.info("活动链路跟踪方法执行完成");
        return ResponseResult.success("活动链路跟踪演示", result);
    }
    
    /**
     * 模拟处理业务逻辑
     */
    private void processBusinessLogic() {
        logger.info("处理业务逻辑开始");
        sleep(100);
        
        // 模拟子步骤
        for (int i = 1; i <= 3; i++) {
            logger.info("处理子步骤 {}", i);
            sleep(30);
        }
        
        logger.info("处理业务逻辑完成");
    }
    
    /**
     * 模拟调用外部服务
     * @return 服务结果
     */
    private Map<String, Object> callExternalService() {
        logger.info("调用外部服务开始");
        sleep(150);
        
        Map<String, Object> result = new HashMap<>();
        result.put("serviceId", "external-service");
        result.put("status", "success");
        result.put("responseTime", 150);
        
        logger.info("调用外部服务完成");
        return result;
    }
    
    /**
     * 休眠指定的毫秒数
     * @param milliseconds 毫秒数
     */
    private void sleep(long milliseconds) {
        try {
            TimeUnit.MILLISECONDS.sleep(milliseconds);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("线程休眠被中断", e);
        }
    }
} 